# encoding:utf-8
import os
import sys
import shutil
import logging
import json
import filecmp
import hashlib


def get_md5(filepath):
    ''' 获取文件md5值 '''
    m5 = hashlib.md5()
    data = file(filepath, "rb")
    while True:
        b = data.read(1024)
        if not b:
            break
        m5.update(b)
    data.close()
    return m5.hexdigest()


class VersionMd5Diff(object):

    ''' 通过文件md5值比较文件 '''

    def __init__(self, basedir, newdir):
        self._basepath = basedir
        self._newpath = newdir
        self._basedata = dict()
        self._tardata = dict()
        self._is_gamelpkg = None
        self._is_conflpkg = None

    def run(self):
        ''' run '''
        self._chk_projpath()

        # baseinfo
        basedic = self._resinfo(self._basepath)
        nverdic = self._resinfo(self._newpath, "res2")

        # file
        jfile = open("E:\\aa.json", "wb")
        jfile.write(json.dumps(basedic, sort_keys=True, indent=4))
        jfile.close()

        jfile2 = open("E:\\bb.json", "wb")
        jfile2.write(json.dumps(nverdic, sort_keys=True, indent=4))
        jfile2.close()

        dif = []
        cmpfname = ""
        for key, fileinfo in nverdic.items():
            # todo script special
            cmpfname = fileinfo["name"]
            if cmpfname.endswith(".lua") or cmpfname.endswith(".luac"):
                if cmpfname.find(os.sep + "config" + os.sep):
                    # conf
                    self._is_conflpkg = True
                else:
                    # gamelogic
                    self._is_gamelpkg = True
            else:
                # newfile
                if basedic.has_key(key) is False:
                    dif.append(fileinfo)
                else:
                    # chgfilen
                    if (fileinfo["md5"] != basedic[key]["md5"]) or (fileinfo["size"] != basedic[key]["size"]):
                        dif.append(fileinfo)

        jfile3 = open("E:\\finalinfo.json", "wb")
        jfile3.write(json.dumps(dif, sort_keys=True, indent=4))
        jfile3.close()

    def _chk_projpath(self):
        ''' 检查文件路径 '''
        if os.path.isdir(self._basepath) == False:
            logging.error("The project resourse path not found!")
            sys.exit()

    def _resinfo(self, respath, ressep="res"):
        infodic = dict()

        def chk_info(path):
            s_size = 0
            s_name = ""
            s_tname = ""
            for pathname in os.listdir(path):
                obj = os.path.join(path, pathname)
                if os.path.isfile(obj) is True:
                    s_size = os.path.getsize(obj)
                    s_name = obj[obj.find(
                        os.sep + ressep + os.sep) + len(os.sep):]
                    s_tname = s_name.replace(ressep, "res", 1)
                    infodic[s_tname] = dict(
                        name=s_tname, size=s_size, md5=get_md5(obj))
                else:
                    if obj.find(".svn") == -1:
                        chk_info(obj)
        chk_info(respath)
        return infodic


class VersionSvnDiff(object):
    ''' 利用svn提交号查看文件差异 '''

    PLAT_SUFFIX = dict(
        android = ".lpkg",
        ios = "64.lpkg"
    )
    
    def __init__(self, svnconf, platform):
        self.NAME = svnconf["svnname"]
        self.PASSWORD = svnconf["svnpwd"]
        self._respath = svnconf["respath"]
        self._svnpath = svnconf["svnpath"]
        self._staridx = svnconf["start_idx"]
        self._endidx = svnconf["end_idx"]
        self._verinfo = svnconf["verinfo"]
        self._verpath = svnconf["verpath"]
        
        self._diflist = None
        self._plat = platform

    # 检查版本间差异并生成对应的的python 字典
    def chk_dif(self):
        startlnum = self._staridx
        endlnum = self._endidx

        diffdic = []
        tmpfile = os.path.join(os.getcwd(), "template.xml")
        # step1
        os.system("cd %s" % self._respath)

        logging.info("Use svn command to chk diffrence in {svnpath} {start}:{end} to {tarxml}...".format(
            svnpath=self._respath, start=startlnum, end=endlnum, tarxml=tmpfile))
        
        # step2 svn command
        cmd_str = "svn log -r {start}:{end} {svnpath} --username {svnname} --password {svnpwd} -v -g --stop-on-copy -g --xml >{outfile}".format(
            start=startlnum, end=endlnum, svnpath=self._respath, outfile=tmpfile, svnname=self.NAME, svnpwd=self.PASSWORD)
        logging.info("cmd_str" + cmd_str)

        os.system(cmd_str)
        logging.info("Chk is lua script had been changed!?...")

        def _filter_res(name):
            if name.find(self._svnpath) != -1:
                if not name.endswith(".lua") and not name.endswith(".luac"):
                    fileobj = name.replace(self._svnpath, "")
                    diffdic.append(fileobj)

        # step3 readxml to dict
        from xml.etree import ElementTree
        try:
            root = ElementTree.parse(tmpfile)
            commitlist = root.findall("logentry")
            for commit in commitlist:
                paths = commit.find("paths").findall("path")
                for path in paths:
                    type = path.get("kind")
                    name = path.text
                    if type == "file":
                        _filter_res(name)
        except Exception, eee:
            logging.info("No xml for chk...\n%s", eee)

        # step4 conf.lpkg game.lpkg
        # todo 优化脚本包大小
        confpkg = "config" + self.PLAT_SUFFIX[self._plat]
        diffdic.append(confpkg)
        logging.info("Yes!%s" % confpkg)
        gamepkg = "game" + self.PLAT_SUFFIX[self._plat]
        diffdic.append(gamepkg)
        logging.info("Yes!%s" % gamepkg)

        # #step5 del file
        os.remove(tmpfile)
        self._diflist = diffdic

    # 复制差异文件到制定路径
    def copy_diffres(self):
        filelist = self._diflist
        verpath = os.path.join(self._verpath, self._verinfo)
        if os.path.isdir(verpath):
            shutil.rmtree(verpath)

        os.mkdir(verpath)
        verpath = os.path.join(verpath, "res")
        os.mkdir(verpath)
        logging.info("Move the %s-fils  to the verpath->%s"
                     ,len(filelist), verpath)

        s_filename = ""
        for filename in filelist:
            s_filename = filename.replace("/", os.sep)
            baseobj = os.path.join(self._respath, s_filename)
            tarobj = os.path.join(verpath, s_filename)
            if os.path.isdir(os.path.split(tarobj)[0]) == False:
                os.makedirs(os.path.split(tarobj)[0])
            logging.debug("[verdiff.py] Copy the new ver file {fromf} to {tof}".format(
                fromf=baseobj, tof=tarobj))
            shutil.copyfile(baseobj, tarobj)
